package com.github.zhijieqing.socket.cluster.redis;

import com.github.zhijieqing.common.web.utils.RedisUtils;
import com.github.zhijieqing.log.utils.JsonUtil;
import com.github.zhijieqing.socket.cluster.common.channel.MsgChannel;
import com.github.zhijieqing.socket.cluster.common.config.Const;
import com.github.zhijieqing.socket.cluster.common.domain.SocketMsg;
import com.github.zhijieqing.socket.cluster.common.manager.SocketManager;
import com.github.zhijieqing.socket.cluster.common.node.SocketServerNode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;

@Slf4j
public class RedisMsgChannel implements MsgChannel {

    @Setter
    private RedissonClient redissonClient;

    @Override
    public void init(SocketManager socketManager) {
        redissonClient.getTopic(getNodeTopic(socketManager.getCurrentServerNode())).addListenerAsync(SocketMsg.class,(channel, socketMsg)->{
            if(log.isDebugEnabled()){
                log.debug("channel:{},收到消息：{}",channel, JsonUtil.writeValueAsString(socketMsg));
            }
            socketManager.onMessage(socketMsg);
        });
        redissonClient.getTopic(getAppTopic(socketManager.getCurrentServerNode())).addListenerAsync(SocketMsg.class,(channel, socketMsg)->{
            if(log.isDebugEnabled()){
                log.debug("channel:{},收到消息：{}",channel, JsonUtil.writeValueAsString(socketMsg));
            }
            socketManager.onMessage(socketMsg);
        });
    }

    @Override
    public void sendMsgToNode(SocketServerNode socketServerNode, SocketMsg msg) {
        String channel=getNodeTopic(socketServerNode);
        if(log.isDebugEnabled()){
            log.debug("channel:{},发送消息：{}",channel, JsonUtil.writeValueAsString(msg));
        }
        redissonClient.getTopic(channel).publishAsync(msg);
    }

    @Override
    public void sendMsgToApp(SocketServerNode socketServerNode, SocketMsg msg) {
        String channel=getAppTopic(socketServerNode);
        if(log.isDebugEnabled()){
            log.debug("channel:{},发送消息：{}",channel, JsonUtil.writeValueAsString(msg));
        }
        redissonClient.getTopic(channel).publishAsync(msg);
    }
    /**
     * 获取节点的topic地址
     * @param socketServerNode
     * @return
     */
    private String getNodeTopic(SocketServerNode socketServerNode){
        return RedisUtils.getKey(Const.SERVER_NODE_TOPIC_PREFIX+socketServerNode.getId());
    }

    /**
     * 获取应用的topic地址
     * @param socketServerNode
     * @return
     */
    private String getAppTopic(SocketServerNode socketServerNode){
        //重新设置，只要是为了不依赖配置的redis key前缀
        return RedisUtils.getKey(Const.SERVER_NODE_TOPIC_PREFIX+socketServerNode.getName());
    }
}
